import requests
import json
import os
from datetime import datetime


class FeishuReporter:
    def __init__(self, app_id, app_secret, webhook_url):
        self.webhook_url = webhook_url
        self.app_id = app_id
        self.app_secret = app_secret
        self.headers = {"Content-Type": "application/json; charset=utf-8"}
        self.access_token = self._get_access_token()
        # 增加token有效期管理
        self.token_expire_time = datetime.now().timestamp() + 3600  # 默认1小时有效期

    def _get_access_token(self):
        """获取access token并增加详细日志"""
        url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal"

        payload = {
            "app_id": self.app_id,
            "app_secret": self.app_secret
        }

        try:
            response = requests.post(
                url,
                headers=self.headers,
                data=json.dumps(payload),
                timeout=10  # 增加超时设置
            )

            # 打印原始响应内容用于调试
            print(f"Token响应状态码: {response.status_code}")
            print(f"Token响应内容: {response.text[:500]}")  # 只显示前500字符

            # 检查状态码
            if response.status_code != 200:
                print(f"获取token失败，HTTP状态码: {response.status_code}")
                return None

            # 尝试解析JSON
            try:
                result = response.json()
            except json.JSONDecodeError as e:
                print(f"解析token响应JSON失败: {str(e)}")
                return None

            if result.get("code") != 0:
                print(f"获取token失败: {result.get('msg')}")
                return None

            return result["tenant_access_token"]
        except Exception as e:
            print(f"获取token过程出错: {str(e)}")
            return None

    def _refresh_token_if_needed(self):
        """检查并刷新过期的token"""
        if datetime.now().timestamp() > self.token_expire_time - 60:  # 提前60秒刷新
            print("Token即将过期，尝试刷新...")
            new_token = self._get_access_token()
            if new_token:
                self.access_token = new_token
                self.token_expire_time = datetime.now().timestamp() + 3600
                return True
            return False
        return True

    def _get_upload_url(self, file_name, file_size):
        """获取文件上传地址，增加错误处理"""
        # 先检查并刷新token
        if not self._refresh_token_if_needed():
            print("Token刷新失败，无法继续")
            return None

        if not self.access_token:
            print("没有有效的access token")
            return None

        url = "https://open.feishu.cn/open-apis/im/v1/files/get_upload_url"

        payload = {
            "file_name": file_name,
            "file_size": file_size,
            "file_type": "stream"
        }

        headers = {
            "Authorization": f"Bearer {self.access_token}",
            "Content-Type": "application/json"
        }

        try:
            response = requests.post(
                url,
                headers=headers,
                data=json.dumps(payload),
                timeout=15
            )

            # 打印调试信息
            print(f"上传地址响应状态码: {response.status_code}")
            print(f"上传地址响应内容: {response.text[:500]}")

            if response.status_code != 200:
                print(f"获取上传地址失败，HTTP状态码: {response.status_code}")
                return None

            # 尝试解析响应
            try:
                result = response.json()
            except json.JSONDecodeError as e:
                print(f"解析上传地址JSON失败: {str(e)}")
                print(f"原始响应内容: {response.text}")
                return None

            if result.get("code") != 0:
                print(f"获取上传地址失败: {result.get('msg')}")
                return None

            return {
                "upload_url": result["data"]["upload_url"],
                "file_key": result["data"]["file_key"]
            }
        except Exception as e:
            print(f"获取上传地址出错: {str(e)}")
            return None

    # 其他方法保持不变...
    def _upload_file(self, upload_url, file_path):
        try:
            with open(file_path, "rb") as f:
                response = requests.put(upload_url, data=f, timeout=30)

            if 200 <= response.status_code < 300:
                return True
            print(f"文件上传失败，状态码: {response.status_code}, 响应: {response.text}")
            return False
        except Exception as e:
            print(f"文件上传出错: {str(e)}")
            return False

    def send_file(self, file_path, message=""):
        if not os.path.exists(file_path):
            print(f"文件不存在: {file_path}")
            return False

        file_name = os.path.basename(file_path)
        file_size = os.path.getsize(file_path)
        print(f"准备发送文件: {file_name}, 大小: {file_size} bytes")

        upload_info = self._get_upload_url(file_name, file_size)
        if not upload_info:
            return False

        if not self._upload_file(upload_info["upload_url"], file_path):
            return False

        payload = {
            "msg_type": "file",
            "content": {
                "file_key": upload_info["file_key"]
            }
        }

        if message:
            payload["content"]["extra"] = {"text": message}

        try:
            response = requests.post(
                self.webhook_url,
                headers=self.headers,
                data=json.dumps(payload),
                timeout=10
            )

            try:
                result = response.json()
            except json.JSONDecodeError:
                print(f"发送响应不是有效的JSON: {response.text}")
                return False

            if result.get("code") != 0:
                print(f"发送文件消息失败: {result.get('msg')}")
                return False

            print(f"文件 {file_name} 已成功发送到飞书")
            return True
        except Exception as e:
            print(f"发送文件出错: {str(e)}")
            return False


# 使用示例（请替换为实际信息）
if __name__ == "__main__":
    APP_ID = "cli_a8063022f59c500b"
    APP_SECRET = "6CKqlOW9EBDpc2p7xqh0NhKGIK3woL5r"
    # FEISHU_WEBHOOK_URL = "https://open.feishu.cn/open-apis/bot/v2/hook/your-webhook-url"
    FEISHU_WEBHOOK_URL ="https://open.feishu.cn/open-apis/bot/v2/hook/540b71a5-58a3-4a5f-9cd7-ff981ebcbc59"

    reporter = FeishuReporter(APP_ID, APP_SECRET, FEISHU_WEBHOOK_URL)
    reporter.send_file("a.txt", "测试发送文件")